package yt.demo.appcoresystem.aspect;

import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import yt.demo.appcommonbean.http.Request;
import yt.demo.appcommontools.utils.Ip2RegionUtils;
import yt.demo.appcommontools.utils.ObjectToMapUtils;
import yt.demo.appcommontools.utils.RequestUtils;
import yt.demo.appcoresystem.dto.LoginDTO;
import yt.demo.appcoresystem.entity.SystemLoginLog;
import yt.demo.appcoresystem.service.ISystemLoginLogService;

import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Aspect
@Component
public class LoginLogAspect {

    @Autowired
    private ISystemLoginLogService loginLogService;

    @Pointcut("execution(* yt.demo.demoadmin.controller.AuthController.login(..))")
    public void loginLogPointcut() {
    }

    @AfterReturning(value = "loginLogPointcut()", returning = "result")
    public void afterLogin(JoinPoint joinPoint, Object result) {
        addLog(joinPoint, result, "returning");

    }

    @AfterThrowing(value = "loginLogPointcut()", throwing = "ex")
    public void afterLoginFailure(JoinPoint joinPoint, Throwable ex) {
        addLog(joinPoint, ex, "throwing");
    }


    private void addLog(JoinPoint joinPoint, Object result, String source) {
        Object[] args = joinPoint.getArgs();
        Map<String, Object> restResponse = ObjectToMapUtils.convertObjectToMap(result);
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        LoginDTO params = (LoginDTO) args[0];
        String ip = Request.getClientIp(request);
        String agent = request.getHeader("User-Agent");
        SystemLoginLog data = new SystemLoginLog();
        data.setIp(ip);
        data.setIpLocation(Ip2RegionUtils.getIpAddress(ip));
        data.setUsername(params.username());
        data.setOs(RequestUtils.os(agent));
        data.setBrowser(RequestUtils.browser(agent));
        data.setStatus(Objects.equals(source, "throwing") ? 0 : (Integer) restResponse.get("code") == 200 ? 1 : 0);
        data.setMessage((String) restResponse.get("message"));
        data.setLoginTime(new Date());
        loginLogService.create(data);
    }
}